package org.extreme.web.plugins.spring;

import java.lang.reflect.Field;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.ServletConfig;

import org.extreme.core.plugin.AbstractPlugin;
import org.extreme.web.core.cfg.WebGlobal;
import org.extreme.web.core.ctrl.ICtrl;
import org.extreme.web.core.util.PathUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

/**
 * depands WebPlugin
 * @author lich
 *
 */
public class SpringPlugin extends AbstractPlugin{
	
	private static String[] configurations;
	private static ApplicationContext ctx;
	

	
	/**
	 * Use configuration under the path of WebRoot/WEB-INF.
	 */
	public SpringPlugin() {
	}
	
	public SpringPlugin(String... configurations) {
		SpringPlugin.configurations = configurations;
	}
	
	public SpringPlugin(ApplicationContext ctx) {
		SpringPlugin.ctx = ctx;
	}
	
	@Override
	public void init(ServletConfig config) {
		if (configurations != null)
			ctx = new FileSystemXmlApplicationContext(configurations);
		else
			ctx = new FileSystemXmlApplicationContext(PathUtil.getWebRootPath() + "/WEB-INF/applicationContext.xml");

		List<ICtrl> ctrls = WebGlobal.getRoutes().getCtrls();
		for(ICtrl c : ctrls){
			Field[] fields = c.getClass().getDeclaredFields();
			for(Field field : fields){
				Object bean = null;
				if (field.isAnnotationPresent(Resource.class))
					bean = ctx.getBean(field.getName());
				else if (field.isAnnotationPresent(Autowired.class))
					bean = ctx.getBean(field.getType());
				else
					continue ;
				
				try {
					if (bean != null) {
						if(!field.isAccessible()){
							field.setAccessible(true);
							field.set(c, bean);
							field.setAccessible(false);
						}else{
							field.set(c, bean);
						}
					}
				} catch (Exception e) {
					throw new RuntimeException(e);
				}
			}
		}
	};
	
	@Override
	public void destroy() {
	}
	
	public static <T> T getBean(Class<T> claz){
		if(ctx==null){
			throw new RuntimeException("spring plugin not init!");
		}
		return ctx.getBean(claz);
	}
	
	public static Object getBean(String name){
		if(ctx==null){
			throw new RuntimeException("spring plugin not init!");
		}
		return ctx.getBean(name);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name,Class<T> claz){
		if(ctx==null){
			throw new RuntimeException("spring plugin not init!");
		}
		return (T)ctx.getBean(name);
	}
}
